//Adam485通讯，使用USART5
#include "adc.h"
#include "adam.h"
#include "defined.h"
#include "uart_tcp.h"
#include "uip.h"
#include "rtc.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

MODBUSMETER *pModbusMeter;
ModbusRTUData Regdata;

float FloatByte3412(u8 *pfloat)
{
	u16 temp;
	temp = *((u16 *)pfloat);
	*((u16 *)pfloat) = *((u16 *)(pfloat+2));
	*((u16 *)(pfloat+2)) = temp;
	return *(float *)(pfloat);
}

void u16_BigEndian_memcpy(u8 * pdes,u8 *psource,u8 len)
	//&Sendbuffer[7],&Regdata.Calendar,Sendbuffer[6]);
{
	u8 i =0;
	for (i=0;i<len;i+=2)
	{
		*(pdes+i) = *(psource+1+i);
		*(pdes+1+i) = *(psource+i);
	}
}

void AnalyseTimeReg(u8 *pregdata)
{
	Regdata.Calendar.w_year = *(u16 *)(pregdata) +0x700;
	Regdata.Calendar.w_month = *(u16 *)(pregdata+2);
	Regdata.Calendar.w_date = *(u16 *)(pregdata+4);
	Regdata.Calendar.hour = *(u16 *)(pregdata+6);
	Regdata.Calendar.min = *(u16 *)(pregdata+8);
	Regdata.Calendar.sec = *(u16 *)(pregdata+10);
}

void AnalyseWsReg(u8 *pregdata)
{
	Regdata.fRTU_Windspeed = FloatByte3412(pregdata+4) ;
	Regdata.fRTU_Winddir = FloatByte3412(pregdata+12) ;
}

void AnalyseTspReg(u8 *pregdata)
{
	Regdata.fRTU_airtemp = FloatByte3412(pregdata);//*(float *)(pregdata) ;
	Regdata.fRTU_ahum = FloatByte3412(pregdata+4) ;
	Regdata.fRTU_noise = FloatByte3412(pregdata+12) ;
	Regdata.fRTU_PM10 = FloatByte3412(pregdata+16) ;
	Regdata.fRTU_PM25 = FloatByte3412(pregdata+20) ;
}

MODBUSMETER ModbusMeter[] ={
	{0x01,	0x03,	684,	6, AnalyseTimeReg},
	{0x01,	0x03,	64,		8, AnalyseWsReg},
	{0x01,	0x03,	84,		12, AnalyseTspReg},
};

unsigned char Cal_BCC(unsigned char *ptr, unsigned char len)
{
	uint8_t bcc=0;
	while(len--!=0)
	{
		bcc = bcc^(*ptr);
		ptr++;
	}
	return bcc;
}

void Modbus_UART_Init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);	//使能USART1，GPIOA时钟以及复用功能时钟
     //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    //USART1_RX	  PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

   //Usart1 NVIC 配置

   //USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
    USART_Init(USART1, &USART_InitStructure); //初始化串口
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
    USART_Cmd(USART1, ENABLE);                    //使能串口 
}

static u8 Modbus_Uart_RX_Buf[128];
static u8 Modbus_Uart_RX_Cnt;
RE_UART_TYPE  Modbus_Uart_Type;   //接收状态类型

void USART1_IRQHandler(void)
{
    u8 Clear=Clear;//这种定义方法,可以用来清除编译器的"没有用到"提醒
    u8 Res;
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收一字节
    {
        USART_ClearFlag(USART1,USART_FLAG_RXNE);
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
        Res=USART_ReceiveData(USART1);
        switch (Modbus_Uart_RX_Cnt)
		{
			case 0:
				if (Res==pModbusMeter->MeterId)
				{
					Modbus_Uart_RX_Buf[Modbus_Uart_RX_Cnt++]=Res;
				}
				break;
			default:
				if (Modbus_Uart_RX_Cnt <128)
				{
					Modbus_Uart_RX_Buf[Modbus_Uart_RX_Cnt++]=Res;
				}
		}
    }
    else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)   //接受完一帧
    {
        Clear=USART1->SR;//读SR寄存器
        Clear=USART1->DR;//读DR寄存器    (先读SR再读DR,为了清除IDLE标识);
		if (Modbus_Uart_RX_Cnt>5)
			Modbus_Uart_Type = RE_UART_NORMAL;
		else 
			Modbus_Uart_RX_Cnt = 0;
    }
}

//------------从机指令发送函数--------------------
void USART1_Send(u8*CmdStr,u16 length)
{
    u16 t;
    SET485_MODBUS;
    for(t=0; t<length; t++)
    {
        UART_SendByte(USART1,*CmdStr++);
    }
    CLR485_MODBUS;
}

void USART1_SendString(u8*Str)
{
    SET485_MODBUS;
    while (*Str != 0x00)
    {
        UART_SendByte(USART1,*Str++);
    }
    return ;
    CLR485_MODBUS;
}

void Send_Cmd03_Modbus(void)
{
    u8 Sendbuffer[10];
    u16 crc16;
    Sendbuffer[0] = pModbusMeter->MeterId;
    Sendbuffer[1] = pModbusMeter->ReadCmd;
    Sendbuffer[2] = (u8)(pModbusMeter->RegAddress>>8);
    Sendbuffer[3] = (u8)pModbusMeter->RegAddress;
    Sendbuffer[4] = (u8)(pModbusMeter->RegNumber>>8);
    Sendbuffer[5] = (u8)(pModbusMeter->RegNumber);    // 数量
    crc16 = CRC16_result(Sendbuffer, 6);
    Sendbuffer[6] = (u8)(crc16);
    Sendbuffer[7] = (u8)(crc16>>8);    // 数量
	
    USART1_Send(Sendbuffer,8);
}

void Send_Cmd10_SetTime_Modbus(void)   //设置时间
{
    u8 Sendbuffer[128];
    u16 crc16;
    Sendbuffer[0] = ModbusMeter[0].MeterId;
    Sendbuffer[1] = 0x10;
    Sendbuffer[2] = (u8)(684>>8);
    Sendbuffer[3] = (u8)(684);
    Sendbuffer[4] = (u8)(ModbusMeter[0].RegNumber>>8);
    Sendbuffer[5] = (u8)(ModbusMeter[0].RegNumber);    // 数量
	Sendbuffer[6] = (u8)(ModbusMeter[0].RegNumber*2);    // 数量
	u16_BigEndian_memcpy(&Sendbuffer[7],(u8 *)&Regdata.Calendar,Sendbuffer[6]);
    crc16 = CRC16_result(Sendbuffer, 7+Sendbuffer[6]);
    Sendbuffer[7+Sendbuffer[6]] = (u8)(crc16);
    Sendbuffer[8+Sendbuffer[6]] = (u8)(crc16>>8);    // 数量
	
    USART1_Send(Sendbuffer,9+Sendbuffer[6]);
}


void Poll_Modbus_Task(void)
{
	static u8 OrderNumber=0;
	pModbusMeter = ModbusMeter+OrderNumber;
	OrderNumber++;
	if (OrderNumber>=(sizeof(ModbusMeter)/sizeof(ModbusMeter[0])))
	{
		OrderNumber=0;
	}
	Send_Cmd03_Modbus();
}

extern u8 testflag;
void Analyse_Modbusdata(void)
{
    u16 crc16;
	u8 ModbusCmd,i;
	u8 ModbusDataLen;
	u8 *pReg,*pFreeReg;
    if (Modbus_Uart_Type != RE_UART_NORMAL)
        return ;
	crc16 = CRC16_result(Modbus_Uart_RX_Buf,Modbus_Uart_RX_Cnt-2);
    if (crc16 != (Modbus_Uart_RX_Buf[Modbus_Uart_RX_Cnt-2] + (Modbus_Uart_RX_Buf[Modbus_Uart_RX_Cnt-1]<<8)))
		{
		Modbus_Uart_RX_Cnt = 0;
		Modbus_Uart_Type = RE_UART_CRC16_ERR;
		return ;
    	}
	switch (Modbus_Uart_RX_Buf[1])
	{
		case 0x03:
			pReg =(u8 *)(malloc(pModbusMeter->RegNumber*2));
			pFreeReg = pReg;
			for (i=0;i<Modbus_Uart_RX_Buf[2]/2;i++)
				{
				*pReg++ = Modbus_Uart_RX_Buf[3+2*i+1];
				*pReg++ = Modbus_Uart_RX_Buf[3+2*i];
				}
			pModbusMeter->pAnalyseFuntion(pFreeReg);   //解析
			free(pFreeReg);
			Modbus_Uart_Type = RE_UART_NULL;
			Modbus_Uart_RX_Cnt = 0;
			break;
		default:
			break;
	}
}

extern TypeEquipmentUDPHandle  EquProlVar;
/* 十六进制数转换为十进制数 */
long hexToDec(char *source,u8 len);
/* 返回ch字符在sign数组中的序号 */
int getIndexOfSigns(char ch);

/* 十六进制数转换为十进制数 */
long hexToDec(char *source,u8 len)
{
    long sum = 0;
    long t = 1;
    int i;//, len;
 
    //len = strlen(source);
    for(i=len-1; i>=0; i--)
    {
        sum += t * getIndexOfSigns(*(source + i));
        t *= 16;
    }  
 
    return sum;
}
 
/* 返回ch字符在sign数组中的序号 */
int getIndexOfSigns(char ch)
{
    if(ch >= '0' && ch <= '9')
    {
        return ch - '0';
    }
    if(ch >= 'A' && ch <='F') 
    {
        return ch - 'A' + 10;
    }
    if(ch >= 'a' && ch <= 'f')
    {
        return ch - 'a' + 10;
    }
    return -1;
}